package org.dicr.gui.io;

import java.awt.*;
import java.awt.image.*;
import java.io.*;

import javax.swing.*;

import org.dicr.event.*;
import org.dicr.gui.*;

/***********************************************************************************************************************
 * @author Igor A Tarasov me@dicr.dn.ua
 * @version 020917
 **********************************************************************************************************************/
public class ImageIO {
	protected long maxFileSize = 500000;

	protected CustomFileFilter fileFilter = new CustomFileFilter();

	protected File imageFile = null;

	/*******************************************************************************************************************
	 * Конструктор
	 ******************************************************************************************************************/
	public ImageIO() {
		try {
			jbInit();
		} catch (Exception ex) {
			DicrExceptionHandler.handleException(ex, this);
		}
	}

	/*******************************************************************************************************************
	 * инициализация
	 ******************************************************************************************************************/
	private void jbInit() {
		this.fileFilter.addExt("JPG");
		this.fileFilter.addExt("GIF");
		this.fileFilter.addExt("PNG");
		this.fileFilter.setDescription("Файлы изображений");
	}

	/*******************************************************************************************************************
	 * Возвращает максимальный размер загружаемого файла
	 ******************************************************************************************************************/
	public long getMaxFileSize() {
		return this.maxFileSize;
	}

	/*******************************************************************************************************************
	 * Устанавливает максимальный размер загружаемого файла
	 ******************************************************************************************************************/
	public void setMaxFileSize(long size) {
		if (size <= 0) throw new IllegalArgumentException("Неверный параметр size=" + size);
		this.maxFileSize = size;
	}

	/*******************************************************************************************************************
	 * Возвращает файл текущего изображения
	 * 
	 * @return file
	 ******************************************************************************************************************/
	public File getImageFile() {
		return this.imageFile;
	}

	/*******************************************************************************************************************
	 * Устанавливает файл текущего изображения
	 * 
	 * @param imageFile
	 ******************************************************************************************************************/
	@SuppressWarnings("hiding")
	public void setImageFile(File imageFile) {
		this.imageFile = imageFile;
	}

	/*******************************************************************************************************************
	 * Загружает изображение из массива данных
	 * 
	 * @param imageData
	 * @return image
	 ******************************************************************************************************************/
	public ImageIcon loadImage(byte[] imageData) {
		if (imageData == null) throw new IllegalArgumentException("null параметр imageData");
		return new ImageIcon(imageData);
	}

	/*******************************************************************************************************************
	 * Загружает файл из потока ввода/вывода
	 * 
	 * @param in
	 * @return image
	 * @throws IOException
	 ******************************************************************************************************************/
	public ImageIcon loadImage(InputStream in) throws IOException {
		if (in == null) throw new IllegalArgumentException("null параметр in");
		ByteArrayOutputStream bou = new ByteArrayOutputStream();
		while (in.available() > 0)
			bou.write(in.read());
		bou.flush();
		byte[] data = bou.toByteArray();
		bou.close();
		return loadImage(data);
	}

	/*******************************************************************************************************************
	 * Загружает изображение из указанного файла
	 * 
	 * @param imageFile
	 * @return image
	 * @throws FileNotFoundException
	 * @throws IOException
	 ******************************************************************************************************************/
	@SuppressWarnings("hiding")
	public ImageIcon loadImage(File imageFile) throws IOException {
		if (imageFile == null) throw new IllegalArgumentException("null параметр imageFile");
		if (imageFile.length() > this.maxFileSize) throw new FileNotFoundException("Ошибка загрузки файла: "
		        + imageFile.getName() + ".\nРазмер файла " + imageFile.length() + " превышает максимальный - "
		        + this.maxFileSize + " байт");
		this.imageFile = imageFile;
		ImageIcon icon = null;
		FileInputStream in = null;
		try {
			in = new FileInputStream(imageFile);
			icon = loadImage(in);
		} finally {
			if (in != null) in.close();
		}
		return icon;
	}

	/*******************************************************************************************************************
	 * Выводит диалог загрузки изображения из файла
	 * 
	 * @param parent
	 * @return icon
	 * @throws IOException
	 * @throws FileNotFoundException
	 ******************************************************************************************************************/
	public ImageIcon loadImage(Component parent) throws IOException, FileNotFoundException {
		ImageIcon icon = null;
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setFileFilter(this.fileFilter);
		fileChooser.setDialogTitle("Загрузка изображения из файла");
		if (this.imageFile != null) fileChooser.setSelectedFile(this.imageFile);
		if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			if (file != null) icon = loadImage(file);
		}
		return icon;
	}

	/*******************************************************************************************************************
	 * Выводит изображение в поток вывода в формате JPEG
	 * 
	 * @param ou
	 * @param image
	 * @throws IOException
	 ******************************************************************************************************************/
	public void saveImage(OutputStream ou, Image image) {
		if (ou == null) throw new IllegalArgumentException("null параметр ou");
		if (image == null) throw new IllegalArgumentException("null параметр image");
		@SuppressWarnings("unused")
        BufferedImage bimage = GuiMisc.makeBufferedImage(image);
		/** DOTO update code to new Java
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(ou);
		JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
		param.setQuality(0.8f, false);
		// TODO: encoder.setJPEGEncodeParam(param);
		encoder.encode(bimage);
		ou.flush();
		*/
	}

	/*******************************************************************************************************************
	 * Сохраняет изображение в указанный файл
	 * 
	 * @param imageFile
	 * @param image
	 * @throws FileNotFoundException
	 * @throws IOException
	 ******************************************************************************************************************/
	@SuppressWarnings("hiding")
	public void saveImage(File imageFile, Image image) throws IOException {
		if (imageFile == null) throw new IllegalArgumentException("null параметр imageFile");
		if (image == null) throw new IllegalArgumentException("null параметр image");
		OutputStream ou = null;
		try {
			ou = new FileOutputStream(imageFile);
			saveImage(ou, image);
		} finally {
			if (ou != null) {
				ou.flush();
				ou.close();
			}
			this.imageFile = imageFile;
		}
	}

	/*******************************************************************************************************************
	 * Сохранение изображения в файл
	 * 
	 * @param image
	 * @param parent
	 * @throws IOException
	 * @throws FileNotFoundException
	 ******************************************************************************************************************/
	public void saveImage(Image image, Component parent) throws IOException, FileNotFoundException {
		if (image == null) throw new IllegalArgumentException("null параметр image");
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
		fileChooser.setFileFilter(this.fileFilter);
		fileChooser.setDialogTitle("Сохранение изображения в файл");
		if (this.imageFile != null) fileChooser.setSelectedFile(this.imageFile);
		while (true) {
			if (fileChooser.showSaveDialog(parent) != JFileChooser.APPROVE_OPTION) break;
			File file = fileChooser.getSelectedFile();
			if (file == null) break;
			if (file.getName().lastIndexOf(".") == -1) file = new File(file.getPath() + ".jpg");
			if (file.exists()
			        && JOptionPane.showConfirmDialog(parent, "Файл " + file.getName()
			                + " уже существует - переписать поверху ?", "Запись изображения в файл",
			                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) continue;
			saveImage(file, image);
			break;
		}
	}
}
